using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Text;
using log4net;

namespace AutoTest.Core.Domain.SnarlNotification
{
    public class Snarl : ISnarl
    {
        private static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

        private const string Localhost = "127.0.0.1";
        private const int DefaultSnarlPort = 9887;

        private readonly string _hostName;
        private readonly int _hostPort;

        public Snarl() : this(Localhost, DefaultSnarlPort)
        {
        }

        public Snarl(string hostName, int hostPort)
        {
            _hostName = hostName;
            _hostPort = hostPort;
        }

        public void Register(string appName)
        {
            SendLine("type=SNP#?version=1.0#?action=register#?app=" + appName);
        }

        public void Unregister(string appName)
        {
            SendLine("type=SNP#?version=1.0#?action=unregister#?app=" + appName);
        }

        public void AddClass(string appName, string className, string classTitle)
        {
            SendLine("type=SNP#?version=1.0#?action=add_class#?app=" + appName + "#?class=" + className + "#?title=" + classTitle);
        }

        public void Notify(string appName, string className, string title, string text, int timeoutInSeconds)
        {
            SendLine("type=SNP#?version=1.0#?action=notification#?app=" + appName + "#?class=" + className + "#?title=" + title + "#?text=" + text + "#?timeout=" + timeoutInSeconds);
        }

        private void SendLine(string snarlCommand)
        {
            var host = new IPEndPoint(IPAddress.Parse(_hostName), _hostPort);
            using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
            {
                try
                {
                    socket.Connect(host);
                    socket.Send(Encoding.ASCII.GetBytes(snarlCommand));
                    socket.Send(Encoding.ASCII.GetBytes("\r\n"));
                    socket.Close();
                }
                catch (SocketException e)
                {
                    Logger.Error("Unable to communicate with Snarl", e);
                }
            }
        }
    }
}